package org.opsli.modulars.business.iot;


import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.opsli.modulars.business.iot.coder.DecoderHandler;
import org.opsli.modulars.business.iot.coder.EncoderHandler;
import org.opsli.modulars.business.iot.handler.BusinessHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author sst
 * @version V1.0
 * @Package com.lysoft.monitoring.iot
 * @date 2019-08-22 14:12
 */
@Component
@ChannelHandler.Sharable
public class TCPServer {

    @Autowired
    private BusinessHandler businessHandler;

    //端口号
    private static Logger logger = LoggerFactory.getLogger(TCPServer.class);
    NioEventLoopGroup boss = new NioEventLoopGroup();//主线程组
    NioEventLoopGroup work = new NioEventLoopGroup();//工作线程组
    private Channel channel;
    public ChannelFuture init(int port){
        ChannelFuture channelFuture = null;
        logger.info("正在启动tcp服务器...");
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();//引导对象
                bootstrap.group(boss, work)//配置工作线程组
                        .channel(NioServerSocketChannel.class)//配置为NIO的socket通道
                        .option(ChannelOption.SO_BACKLOG, 1024)//缓冲区
                        .option(ChannelOption.SO_RCVBUF, 32 * 1024)
                        .childOption(ChannelOption.SO_KEEPALIVE, true)//ChannelOption对象设置TCP套接字的参数，非必须步骤
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            protected void initChannel(SocketChannel ch) throws Exception {//绑定通道参数
                                ch.pipeline().addLast("encode", new EncoderHandler());//编码器。发送消息时候用
                                ch.pipeline().addLast("decode", new DecoderHandler());//解码器，接收消息时候用
                                ch.pipeline().addLast("handler", businessHandler);//业务处理类，最终的消息会在这个handler中进行业务处理
                            }
                        });
            channelFuture = bootstrap.bind(port).sync();//使用了Future来启动线程，并绑定了端口
            logger.info("启动tcp服务器启动成功，正在监听端口:"+port);
            //future.channel().closeFuture().sync();//以异步的方式关闭端口
            channel = channelFuture.channel();

        }catch (InterruptedException e) {
            logger.info("启动出现异常："+e);
        }finally {
            if (channelFuture != null && channelFuture.isSuccess()) {
                logger.info("netty正在监听端口 " + port + ", 等待连接");
            } else {
                logger.error("netty启动失败！");
            }
        }
        return channelFuture;
    }

    /**
     * 关闭netty服务
     */
    public void closeServer() {
        logger.info("关闭netty服务。。。");
        if (channel != null) {
            channel.close();
        }
        boss.shutdownGracefully();
        work.shutdownGracefully();
        logger.info("关闭netty服务成功！");
    }
}
